/*
 * designassignment5.c
 *
 * Created: 3/23/2014 1:09:30 AM
 *  Author: Yosemit Xolalpa Rosales
 */ 

#define F_CPU 8000000UL		// XTAL = 8 mhz

#include <util/delay.h>		
#include <avr/io.h>			
#include <avr/interrupt.h>	

int onesecvar = 0;			// Var for 1 Sec Clock Val
int analogval = 0;			// Var for Analog Read Value
int LEDTermVal[4];			// Var for Value sent to LED/TERMINAL

void digit_by_digit(int number);
void toterminal(int n);
void com_by_usart(unsigned char ch);


ISR(TIMER1_OVF_vect)
{
	// OCCURENCE IS EVER HALF SECOND, THE COMPARE BELOW ALLOWS US TO SKIP ONE HALF FOR 1SEC TRAVEL

	if(onesecvar==2)
	{	
		onesecvar=0;		// REINIT onesecvar to 0
		
		LEDTermVal[0] = 0; // Clearing values of LEDTermVal
		LEDTermVal[1] = 0;
		LEDTermVal[2] = 0;
		LEDTermVal[3] = 0;
		
		int faren = (analogval*10) * 9 /5 +3200;	// Celsius to Farenheit Conversion
		toterminal(faren);							// Val sent to Terminal
		
		int faren_cp= faren;						// duplicate faren_cp
		int i = 3;									// INTIALIZE place index
				
		do {
			int digit = faren_cp% 10;		// SMALLEST DIGIT
			LEDTermVal[i] = digit;			// SET SMALLEST DIGIT TO RIGHT OF NUMBER
			faren_cp/= 10;					// MOVE TO NEXT DIGIT
			i--;							// NEXT DIGIT
			} 
			while (faren_cp> 0);
	}
	onesecvar++;
}

//--------------------------------------------------------------------------
//-- FUNCTION TO INITIALIZE USART USAGE
//*****	ENABLE transmit and receive, SET unsynchronized, SET Scalar to 9600 baud rate
void usart_init (void)
{
	UCSR0B = (1<<RXEN0)|(1<<TXEN0);
	UCSR0C = ((1<<UCSZ01)|(1<<UCSZ00)|(0<<UMSEL00));
	UBRR0L = 51;										
}

//---------------------------------------------------------------------------
//-- FUNCTION TO INTIALIZE ADC
//***** Initialize the ADC, CLEAR ADCSRB, SET READ FROM ADC0
void adc_init()
{	
	ADCSRA = 0xE7;
	ADCSRB =0x00;
	DIDR0 = 0x3E;
}
//--------------------------------------------------------------------------
//-- FUNCTIONS TO SET-UP USART COMMUNICATIONS & CONVERT NUMBER TO CHAR
void com_by_usart (unsigned char ch)
{
	while(! (UCSR0A & (1<<UDRE0)));		// WAIT FOR DONE SIGNAL
	UDR0 = ch;							// SET UDR0 & SEND CHAR
}
void digit_by_digit(int number)	
{
	com_by_usart (number+48);			// SHIFT INT TO CHAR
}
//----------------------------------------------------------------------------
//-- FUNCTION TO OUTPUT TO LED (Creates a our look-up table)
int LEDoutput(int n){
	
	int val = 0x00;
	switch(n) {
		
		case 0:				// DISPLAY 0
		val= 0x3F;
		break;
		
		case 1:				// DISPLAY 1
		val= 0x18;
		break;
		
		case 2:				// DISPLAY 2
		val= 0x6D;	
		break;
		
		case 3:				// DISPLAY 3
		val= 0x7C;
		break;
		
		case 4:				// DISPLAY 4
		val= 0x5A;
		break;
		
		case 5:				// DISPLAY 5
		val= 0x76;
		break;
		
		case 6:				// DISPLAY 6
		val= 0x77;
		break;
		
		case 7:				// DISPLAY 7
		val= 0x1C;
		break;
		
		case 8:				// DISPLAY 8
		val= 0x7F;
		break;
		
		case 9:				// DISPLAY 9
		val= 0x7E;
		break;
				
	}
	return val;
}


//----------------------------------------------------------------------------------------------
//------ FUNCTION TO OUTPUT TO TERMINAL
//*** outputs 4 Digit Decimal Number to Terminal
void toterminal(int n)
	{
		int LEDTermVal[4] = {0,0,0,0};			// Initialize Buffer
		int i = 3;								// Initialize index
		if(n==0)								// IF 0 send 0
		{
			digit_by_digit(0);
		}
		else
		{										// ELSE
			do 
			{
				int digit = n % 10;				// SMALLEST DIGIT
				LEDTermVal[i] = digit;			// SET SMALLEST DIGIT TO RIGHT OF NUMBER
				n /= 10;						// MOVE TO NEXT DIGIT
				i--;							// NEXT DIGIT
			} while (n > 0);
		
		
			int mezero = 0;						// Comparison val for next loop
			i = 0;
			
			while(i!=4)
			{
				if(LEDTermVal[i]!=0) mezero = 1;				// IT WAS NOT ZERO!
				if(mezero==1) digit_by_digit(LEDTermVal[i]);	// RELAY DIGIT
				if(i==1) com_by_usart ('.');					// PLACE DECIMAL POINT AFTER SECOND NUMBER
				i++;
			}
		}
		com_by_usart(13);										// SEND "CARRIAGE-RETURN" LINE FEED TO TERMINAL
	}
	//----------------------------------------------------------------------------
	// -- LE MAIN FUNCTION
	int main(void)
	{
		DDRB = 0xFF;					// ENABLE PORT B
		DDRD = 0x3E;					// ENABLE PORT D as selector and TX/RX
		PORTD = 0x3E;
		usart_init();					// INITIALIZE USART
		adc_init();						// INITIALIZE ADC
		
		TCCR1A = 0x00;
		TCCR1B = 0x03;
		
		EICRA = 0x02;					// INTERRUPT ON FALLING EDGE
		TIMSK1 = 1;						// ENABLE OVERFLOW INTERRUPT
		sei();							// ALLOW INTERRUPTS
		
		while(1)
		{

			analogval = ADCH *256 + ADCL;
			PORTD = 0x3A;						// SET LED0
			PORTB = LEDoutput(LEDTermVal[0]);	// LIGHT 1ST DIGIT
			_delay_ms(1);

			PORTD = 0x36;						// SET LED1
			PORTB = LEDoutput(LEDTermVal[1]);	// LIGHT 2ND DIGIT
			PORTB |= 0x80;//SET DECIMAL POINT
			_delay_ms(1);

			PORTD = 0x2E;						// SET LED2
			PORTB = LEDoutput(LEDTermVal[2]);	// LIGHT 3RD DIGIT
			_delay_ms(1);

			PORTD = 0x1E;						// SET LED3
			PORTB = LEDoutput(LEDTermVal[3]);	// LIGHT FOURTH DIGIT
			_delay_ms(1);
			PORTD = 0x3E;						// RESET (LED'S TURNED OFF)
		}
		return 0;
	}